home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / mtools.lha / mtools-2.0.7 / mmd.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  5KB  |  225 lines

  1. /*
  2.  * Make an MSDOS subdirectory
  3.  *
  4.  * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  5.  * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  6.  * fthood!egray@uxc.cso.uiuc.edu    Directorate of Engineering & Housing
  7.  *                     Environmental Management Office
  8.  *                     Fort Hood, TX 76544-5057
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <signal.h>
  13. #include "msdos.h"
  14. #include "patchlevel.h"
  15.  
  16. int fd = -1;                /* the file descriptor for the device */
  17. int dir_start;                /* starting sector for directory */
  18. int dir_len;                /* length of directory (in sectors) */
  19. int dir_entries;            /* number of directory entries */
  20. int clus_size;                /* cluster size (in sectors) */
  21. char *mcwd;                /* the Current Working Directory */
  22. int fat_error;                /* FAT error detected? */
  23.  
  24. static int got_signal();
  25. static void empty_dir();
  26.  
  27. main(argc, argv)
  28. int argc;
  29. char *argv[];
  30. {
  31.     int i, entry, slot, fargn, verbose, oops, got_one, missed_one;
  32.     extern unsigned int end_fat;
  33.     unsigned int fat, dot, next_fat();
  34.     char filename[13], *newfile, drive, get_drive(), *get_path();
  35.     char *strcpy(), *fix_mcwd(), *pathname, *unix_name(), last_drive;
  36.     unsigned char *fixed, *dos_name();
  37.     void exit(), fat_write(), dir_write(), disk_flush(), dir_flush();
  38.     struct directory *dir, *dir_read(), *mk_entry();
  39.     long time(), now;
  40.                     /* catch signals */
  41.     signal(SIGINT, (SIG_TYPE(*) ()) got_signal);
  42.     signal(SIGTERM, (SIG_TYPE(*) ()) got_signal);
  43.     signal(SIGQUIT, (SIG_TYPE(*) ()) got_signal);
  44.  
  45.     fargn = 1;
  46.     verbose = 0;
  47.     oops = 0;
  48.     got_one = 0;
  49.     missed_one = 0;
  50.     if (argc > 1) {
  51.         if (!strcmp(argv[1], "-v")) {
  52.             fargn = 2;
  53.             verbose = 1;
  54.         }
  55.         if (argv[1][0] == '-' && !verbose)
  56.             oops++;
  57.     }
  58.     if (argc == 1 || oops) {
  59.         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  60.         fprintf(stderr, "Usage: %s [-v] msdosdirectory [msdosdirectories...]\n", argv[0]);
  61.         exit(1);
  62.     }
  63.     last_drive = 'x';
  64.     mcwd = fix_mcwd();
  65.  
  66.     for (i = fargn; i < argc; i++) {
  67.         drive = get_drive(argv[i]);
  68.         if (drive != last_drive) {
  69.             if (last_drive != 'x') {
  70.                 fat_write();
  71.                 dir_flush();
  72.                 disk_flush();
  73.             }
  74.  
  75.             if (init(drive, 2)) {
  76.                 fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
  77.                 missed_one++;
  78.                 continue;
  79.             }
  80.             last_drive = drive;
  81.         }
  82.                     /* serves the get_name() function too */
  83.         fixed = dos_name(argv[i], verbose);
  84.  
  85.         strcpy(filename, unix_name(fixed, fixed + 8));
  86.         pathname = get_path(argv[i]);
  87.  
  88.         if (subdir(drive, pathname)) {
  89.             missed_one++;
  90.             continue;
  91.         }
  92.                     /* see if exists and get slot */
  93.         slot = -1;
  94.         dot = 0;
  95.         oops = 0;
  96.         for (entry = 0; entry < dir_entries; entry++) {
  97.             dir = dir_read(entry);
  98.  
  99.                     /* if empty */
  100.             if (dir->name[0] == 0x0) {
  101.                 if (slot < 0)
  102.                     slot = entry;
  103.                 break;
  104.             }
  105.                     /* if erased */
  106.             if (dir->name[0] == 0xe5) {
  107.                 if (slot < 0)
  108.                     slot = entry;
  109.                 continue;
  110.             }
  111.                     /* if not a directory */
  112.             if (!(dir->attr & 0x10))
  113.                 continue;
  114.  
  115.             newfile = unix_name(dir->name, dir->ext);
  116.                     /* save the 'dot' directory info */
  117.             if (!strcmp(".", newfile))
  118.                 dot = dir->start[1] * 0x100 + dir->start[0];
  119.  
  120.             if (!strcmp(filename, newfile)) {
  121.                 fprintf(stderr, "%s: Directory \"%s\" already exists\n", argv[0], filename);
  122.                 oops++;
  123.                 break;
  124.             }
  125.         }
  126.         if (oops) {
  127.             missed_one++;
  128.             continue;
  129.         }
  130.                     /* no '.' entry means root directory */
  131.         if (dot == 0 && slot < 0) {
  132.             fprintf(stderr, "%s: No directory slots\n", argv[0]);
  133.             missed_one++;
  134.             continue;
  135.         }
  136.                     /* make the directory grow */
  137.         if (dot && slot < 0) {
  138.             if (dir_grow(dot)) {
  139.                 fprintf(stderr, "%s: Disk full\n", argv[0]);
  140.                 missed_one++;
  141.                 continue;
  142.             }
  143.                     /* first slot in the new part */
  144.             slot = entry;
  145.         }
  146.                     /* grab a starting cluster */
  147.         if ((fat = next_fat(0)) == 1) {
  148.             fprintf(stderr, "%s: Disk full\n", argv[0]);
  149.             missed_one++;
  150.             continue;
  151.         }
  152.                     /* make directory entry */
  153.         time(&now);
  154.         dir = mk_entry(fixed, 0x10, fat, 0L, now);
  155.         dir_write(slot, dir);
  156.                     /* write the cluster */
  157.         empty_dir(fat, dot);
  158.         fat_encode(fat, end_fat);
  159.         got_one++;
  160.     }
  161.                     /* write the FAT, flush the buffers */
  162.     fat_write();
  163.     dir_flush();
  164.     disk_flush();
  165.     close(fd);
  166.     if (got_one && missed_one)
  167.         exit(2);
  168.     if (missed_one)
  169.         exit(1);
  170.     exit(0);
  171. }
  172.  
  173. /*
  174.  * Write an empty directory 'template' to the cluster starting at 'dot'.
  175.  */
  176.  
  177. static void
  178. empty_dir(dot, dot_dot)
  179. unsigned int dot, dot_dot;
  180. {
  181.     int buflen;
  182.     long start;
  183.     char buf[MAX_CLUSTER], *memcpy(), *memset();
  184.     struct directory *dir, *mk_entry();
  185.     void disk_write();
  186.     long time(), now;
  187.  
  188.     start = (long) (dot - 2) * clus_size + dir_start + dir_len;
  189.  
  190.     buflen = clus_size * MSECTOR_SIZE;
  191.     time(&now);
  192.                     /* make the '.' and '..' entries */
  193.     dir = mk_entry((unsigned char *) ".          ", 0x10, dot, 0L, now);
  194.     memcpy(&buf[0], (char *) dir, MDIR_SIZE);
  195.     dir = mk_entry((unsigned char *) "..         ", 0x10, dot_dot, 0L, now);
  196.     memcpy(&buf[MDIR_SIZE], (char *) dir, MDIR_SIZE);
  197.  
  198.                     /* zero the remainder */
  199.     memset(&buf[2 * MDIR_SIZE], '\0', buflen - (2 * MDIR_SIZE));
  200.  
  201.                     /* write the cluster */
  202.     disk_write(start, (unsigned char *) buf, buflen);
  203.     return;
  204. }
  205.  
  206. /*
  207.  * Do a graceful exit if the program is interrupted.  This will reduce
  208.  * (but not eliminate) the risk of generating a corrupted disk on
  209.  * a user abort.
  210.  */
  211.  
  212. static int
  213. got_signal()
  214. {
  215.     void exit(), disk_flush(), fat_write(), dir_flush();
  216.  
  217.     if (fd < 0)
  218.         exit(1);
  219.     fat_write();
  220.     dir_flush();
  221.     disk_flush();
  222.     close(fd);
  223.     exit(1);
  224. }
  225.